import java.util.Random;
import java.util.concurrent.CountDownLatch;

/**
 * 编写代码, 基于 CountDownLatch 模拟跑步比赛的过程
 *
 *
 * @Date 2022-06-23
 */
public class Thread_2549 {
    // 定义参赛选手数量
    private static int playerCount = 5;
    // 定义选手准备的CountDownLatch
    private static CountDownLatch standby   = new CountDownLatch(playerCount);
    // 定义起跑的CountDownLatch
    private static CountDownLatch start   = new CountDownLatch(1);
    // 定义选手到达终点的CountDownLatch
    private static CountDownLatch finished  = new CountDownLatch(playerCount);

    static class Runner implements Runnable {
        @Override
        public void run() {
            // 准备就绪，计数减1
            System.out.println(Thread.currentThread().getName() + " 准备就绪.");
            standby.countDown();
            try {
                // 等待开始比赛
                start.await();
                System.out.println(Thread.currentThread().getName() + "出发");
                // 模拟比赛用时
                Random random = new Random();
                int time = random.nextInt(10) + 10;
                Thread.sleep(time);
                System.out.println(Thread.currentThread().getName() + "到在终点，用时 " + time + "秒.");
                // 计数减1
                finished.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 定义选手线程并启动
        for (int i = 0; i < playerCount; i++) {
            new Thread(new Runner(), "player " + (i + 1)).start();
        }
        // 等待选手准备
        standby.await();
        // 等待参赛选手准备就绪
        System.out.println("所有参赛选手准备就绪，比赛开始...");
        // 发令枪响
        start.countDown();
        // 比赛中，等待选手到达终点
        finished.await();
        System.out.println("比赛结束.");
    }
}